using System.Data;
using Firestarter.DB.Schema.BO;
using FireStarterModeller.BO;
using Firestarter.DB.Schema.Logic;
using Habanero.Base;
using Habanero.Testability;


namespace Firestarter.DB.Schema.Test.Logic
{
    public class TestUtilsSchema
    {
        private readonly DBSchemaBuilder _dbSchemaBuilder;

        public TestUtilsSchema(DBSchemaBuilder dbSchemaBuilder)
        {
            _dbSchemaBuilder = dbSchemaBuilder;
        }
        
        private static string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }
        internal DBDatabase GetDatabaseInfo(string untouchedTableName, out DBTable untouchedDBTable, string toDeleteTableName, out DBTable toDeleteDBTable)
        {
            DBDatabase dbDatabase = new DBDatabase();
            untouchedDBTable = CreateTableInfoWithColumn(untouchedTableName, GetRandomString());
            toDeleteDBTable = CreateTableInfoWithColumn(toDeleteTableName, GetRandomString());
            dbDatabase.Tables.Add(untouchedDBTable);
            dbDatabase.Tables.Add(toDeleteDBTable);
            return dbDatabase;
        }

        internal DBTable CreateTableInfoForeignKeyWith2Columns_WithReferencedTable(string foreignKeyTableName, string foreignKeyColumnName, string referencedTableName, string referencedColumnName, string foreignKeyColumnName2, string referencedColumnName2)
        {
            DBTable referencedDBTable;
            DBTable dbTable = CreateTableInfoWithForeignKeyWithReferencedTable(foreignKeyTableName, foreignKeyColumnName, referencedTableName, referencedColumnName, out referencedDBTable);
            DBColumn foreignKeyColumnbInfo2 = dbTable.Columns.CreateBusinessObject();
            foreignKeyColumnbInfo2.ColumnName = foreignKeyColumnName2;
            DBColumn referencedDBColumnInfo2 = referencedDBTable.Columns.CreateBusinessObject();
            referencedDBColumnInfo2.ColumnName = referencedColumnName2;
            return dbTable;
        }

        internal DBTable CreateTableInfoWithForeignKeyWithReferencedTable(string tableName, string columnName, string referencedTableName, string referencedColumnName, out DBTable referencedDBTable)
        {
            DBTable foreignKeyDBTable = CreateTableInfoWithForeignKeyNoReferencedTable(tableName, columnName);
            IDBDatabase dbDatabase = foreignKeyDBTable.Database;
            referencedDBTable = dbDatabase.Tables.CreateBusinessObject();
            referencedDBTable.TableName = referencedTableName;
            DataTable dataTable = DBSchemaBuilder.GetColumnsDataTable();
            _dbSchemaBuilder.CreateColumnDataRow(dataTable, referencedTableName, referencedColumnName);
            SetupTableInfoColumnsFromDataTable(referencedDBTable, dataTable);
            return foreignKeyDBTable;
        }

        internal DBTable CreateTableInfoWithForeignKeyNoReferencedTable(string tableName, string columnName)
        {
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.Tables.CreateBusinessObject();
            dbTable.TableName = tableName;
            DataTable dataTable = DBSchemaBuilder.GetColumnsDataTable();
            _dbSchemaBuilder.CreateColumnDataRow(dataTable, tableName, columnName);
            SetupTableInfoColumnsFromDataTable(dbTable, dataTable);
            return dbTable;
        }

        internal DBTable CreateTableInfoWithTwoColumn(string tableName, string columnName, string columnName2)
        {
            DataTable dataTable = _dbSchemaBuilder.CreateDataTableWithTwoColumn(tableName, columnName, columnName2);
            DBTable dbTable = SetupTableInfoColumnsFromDataTable(tableName, dataTable);
            
            return dbTable;
        }

        internal DBTable CreateTableInfoWithColumn(string tableName, string columnName)
        {
            DataTable dataTable = _dbSchemaBuilder.CreateDataTableWithOneColumn(tableName, columnName);
            DBTable dbTable = SetupTableInfoColumnsFromDataTable(tableName, dataTable);
            return dbTable;
        }

        private static DBTable SetupTableInfoColumnsFromDataTable(string tableName, DataTable dataTable)
        {
            DBTable dbTable = new DBTable();
            dbTable.TableName = tableName;
            SetupTableInfoColumnsFromDataTable(dbTable, dataTable);
            return dbTable;
        }

        private static void SetupTableInfoColumnsFromDataTable(DBTable dbTable, DataTable dataTable)
        {
            DBSchemaExtractor_Fake dbSchemaExtractorFake = new DBSchemaExtractor_Fake{ColumnsDataTable = dataTable};
            DatabaseReverseEngineerer databaseReverseEngineerer = new DatabaseReverseEngineerer(new ReverseEngineeringSettings(), dbSchemaExtractorFake);
            databaseReverseEngineerer.PopulateColumns(dbTable, dataTable);
        }
    }
}